package com.xqboss.apps.service.equipment;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.convert.equipment.EquipmentAttrPointRatioConverter;
import com.xqboss.apps.convert.equipment.EquipmentAttrTemplateConverter;
import com.xqboss.apps.domain.equipment.Equipment;
import com.xqboss.apps.domain.equipment.EquipmentAttrPointRatio;
import com.xqboss.apps.domain.equipment.EquipmentAttrTemplate;
import com.xqboss.apps.dto.equipment.EquipmentAttrPointRatioDto;
import com.xqboss.apps.dto.equipment.EquipmentAttrTemplateDto;
import com.xqboss.apps.mapper.equipment.EquipmentAttrTemplateMapper;
import com.xqboss.apps.mapper.equipment.EquipmentMapper;
import com.xqboss.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;

/**
 * @author Trent
 * @date 2023/8/16
 */
@Service
public class EquipmentAttrTemplateService extends ServiceImpl<EquipmentAttrTemplateMapper, EquipmentAttrTemplate> {


    @Autowired
    private EquipmentAttrTemplateConverter equipmentAttrTemplateConverter;

    @Autowired
    private EquipmentAttrPointRatioConverter equipmentAttrPointRatioConverter;

    @Autowired
    private EquipmentAttrPointRatioService equipmentAttrPointRatioService;

    /**
     * 新增装备属性模板
     * @param templateDto
     */
    @Transactional(rollbackFor = Exception.class)
    public void insert(EquipmentAttrTemplateDto templateDto) {
        checkParams(templateDto);
        EquipmentAttrTemplate template = equipmentAttrTemplateConverter.fromDto(null, templateDto);
        save(template);
        equipmentAttrPointRatioService.save(template.getId(), templateDto.getPointRatioList());
    }

    /**
     * 更新装备属性模板
     * @param id
     * @param templateDto
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(Long id, EquipmentAttrTemplateDto templateDto) {
        checkParams(templateDto);
        EquipmentAttrTemplate template = equipmentAttrTemplateConverter.fromDto(id, templateDto);
        boolean result = updateById(template);
        if(!result){
            throw new ServiceException("更新失败！");
        }
        // 删除所有爆率属性
        equipmentAttrPointRatioService.removeByTemplateId(template.getId());
        // 保存新的爆率属性配置
        equipmentAttrPointRatioService.save(template.getId(), templateDto.getPointRatioList());
    }

    /**
     * 检测参数是否合法
     * @param dto
     */
    private void checkParams(EquipmentAttrTemplateDto dto){
        if(dto.getLuckRatioMax().doubleValue() < dto.getLuckRatioMin().doubleValue()){
            throw new ServiceException("幸运值区间设置错误");
        }
        if(dto.getStrongRatioMax().doubleValue() < dto.getStrongRatioMin().doubleValue()){
            throw new ServiceException("坚固值区间设置错误");
        }
        if(dto.getDurableRatioMax().doubleValue() < dto.getDurableRatioMin().doubleValue()){
            throw new ServiceException("耐久值区间设置错误");
        }
        if(dto.getTalentRatioMax().doubleValue() < dto.getTalentRatioMin().doubleValue()){
            throw new ServiceException("天赋值区间设置错误");
        }

        BigDecimal totalRatio = dto.getPointRatioList().stream().reduce(BigDecimal.ZERO, (accumulator, item) -> accumulator.add(item.getRatio()), BigDecimal::add);
        if(BigDecimal.ONE.compareTo(totalRatio) != 0){
            throw new ServiceException("爆率比例总和错误");
        }
    }
}
